package com.snap.vseries.ui;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.TextView;

import com.orhanobut.logger.Logger;
import com.snap.vseries.R;
import com.snap.vseries.base.BaseActivity;
import com.snap.vseries.bean.SerialPortDevice;
import com.snap.vseries.serial.Cmd;
import com.snap.vseries.serial.SerialPortHelper;
import com.snap.vseries.service.ExpController;
import com.snap.vseries.service.PcrService;
import com.snap.vseries.ui.widget.DialogView;
import com.snap.vseries.ui.widget.TextButton;
import com.snap.vseries.utils.ToastUtils;
import com.snap.vseries.utils.TopTitleUtils;

import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;

import static com.snap.vseries.AppConfig.SERIAL_BAUD_RATE;
import static com.snap.vseries.AppConfig.SERIAL_PORT;
import static com.snap.vseries.AppConfig.TEMP_TYPE_COUNT;

public class TempDriftSettingActivity extends BaseActivity {
    @BindView(R.id.save_setting_btn)
    protected TextButton saveSettingBtn;
    @BindView(R.id.read_setting_btn)
    protected TextButton readSettingBtn;
    private SerialPortHelper serialPortHelper;
    List<TextView> mTextViewList = new ArrayList<>();
    String[] arr = new String[4];
    @BindView(R.id.tv_37)
    TextView tv37;
    @BindView(R.id.tv_55)
    TextView tv55;
    @BindView(R.id.tv_72)
    TextView tv72;
    @BindView(R.id.tv_95)
    TextView tv95;
    private ScheduledExecutorService executor;
    //保存前温漂数据
    private StringBuffer beforeSaveContent;

    private int deviceId = 0x01;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            PcrService.PcrBinder binder = (PcrService.PcrBinder) service;
            ExpController expController = binder.getService().getCurrentController();
            deviceId = expController.getDeviceId();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };

    /**
     * 读温漂
     */

    public void onCallback(boolean isSuccess, byte[] data) {
        if (!isSuccess) {
            Logger.e("查询温漂失败");
            return;
        }
        if (!Cmd.cmdValidate(data)) {
            Logger.e("查询温漂：状态帧校验失败");
            return;
        }
        beforeSaveContent.setLength(0);
        //帧头(0xA5 0x5A) + 设备地址01+帧长00 0E+帧类型 03（02查询帧 03状态帧）+03对应查询帧的查询码（查询码 03H 查询PID参数 04H 查询温漂 ）+ 校验(1 byte)
        //A5 5A 01 00 0E 03 03 00 00 00 00 00 00 00 00 15
        if (data == null || data.length < 10) {
            return;
        }
        byte[] result = new byte[8];
        System.arraycopy(data, 7, result, 0, 8);
        for (int i = 0; i < arr.length; i++) {
            int index = i * 2;
            short value = (short) (((result[index] & 0xff) << 8) + (result[index + 1] & 0xff));
            DecimalFormat df = new DecimalFormat("0.00");
            String valueString = df.format(value / 100f);
            arr[i] = valueString;
        }
        runOnUiThread(() -> {
            for (int i = 0; i < mTextViewList.size(); i++) {
                mTextViewList.get(i).setText(arr[i]);
                beforeSaveContent.append(arr[i]);
            }
        });


    }


    private WriteAsyncTask writeAsyncTask;
    private Dialog dialog;


    @Override
    protected int layoutResId() {
        return R.layout.activity_temp_setting;
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = new Intent(this, PcrService.class);
        bindService(intent, connection, BIND_AUTO_CREATE);
//        LogViewApi.bind(this);
        initViews();
        this.serialPortHelper = new SerialPortHelper(new SerialPortDevice(SERIAL_PORT, SERIAL_BAUD_RATE));
        this.executor = Executors.newScheduledThreadPool(1);

        try {
            executor.schedule(new ReadTempTask(), 0, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @SuppressLint("StaticFieldLeak")
    private void initViews() {
        new TopTitleUtils(this).setTitle("温漂设置");
        initTextView();
        saveSettingBtn.setOnClickListener(v -> {
            if (contentIsChanged()) {
                //设置pid
                writeAsyncTask = new WriteAsyncTask("保存中...");
                writeAsyncTask.execute();
            } else {
                Logger.i("PID设置，数据没有变化，无法更新！");
                ToastUtils.get().showText("数据没有变化，无法更新！");
            }
        });
        readSettingBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    executor.schedule(new ReadTempTask(), 0, TimeUnit.MILLISECONDS);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private void initTextView() {
        mTextViewList.add(tv37);
        mTextViewList.add(tv55);
        mTextViewList.add(tv72);
        mTextViewList.add(tv95);
        for (int i = 0; i < mTextViewList.size(); i++) {
            TextView textView = mTextViewList.get(i);
            textView.setOnClickListener(v -> showDialog(v, textView.getText().toString()));
        }
    }

    private void showDialog(View view, String text) {
        DialogView dialogView = new DialogView(this)
                .setTitle("请输入数值")
                .setContentType(true)
                .setEditContent(text)
                .setOnClickListener(content -> {
                    try {
                        content = new DecimalFormat("0.#####").format(Double.valueOf(content));
                    } catch (NumberFormatException e) {
                        ToastUtils.get().showText("输入的值不符合规范");
                        return;
                    }
                    if (Double.valueOf(content) < -10 || Double.valueOf(content) > 10) {
                        ToastUtils.get().showText("取值范围为：[-10,10]");
                        return;
                    }
                    for (int i = 0; i < mTextViewList.size(); i++) {
                        if (view.getId() == mTextViewList.get(i).getId()) {
                            mTextViewList.get(i).setText(content);
                            return;
                        }
                    }
                });
        dialogView.show();
    }

    @Override
    protected void onDestroy() {
        if (connection != null) {
            unbindService(connection);
        }
        if (writeAsyncTask != null) {
            writeAsyncTask.cancel(true);
        }
        super.onDestroy();
    }

    /**
     * 内容是否有变化
     */
    private boolean contentIsChanged() {
        StringBuffer finalContent = new StringBuffer();
        for (int i = 0; i < mTextViewList.size(); i++) {
            finalContent.append(mTextViewList.get(i).getText().toString());
        }
        return !beforeSaveContent.toString().equals(finalContent.toString());
    }

    public void showLoading(String content) {
        if (dialog == null) {
            dialog = new Dialog(this, R.style.DimDialogStyle);
            dialog.setContentView(R.layout.dialog_loading);
            dialog.setCanceledOnTouchOutside(true);
            dialog.setCancelable(true);
        }
        TextView contentTv = dialog.findViewById(R.id.content_tv);
        contentTv.setText(content);
        dialog.show();
    }

    public void dismissLoading() {
        if (dialog != null) {
            dialog.dismiss();
        }
    }

    /**
     * 读取pid任务
     */
    private class ReadTempTask implements Runnable {
        @Override
        public void run() {
            try {
                beforeSaveContent = new StringBuffer();
                byte[] cmd = Cmd.queryTempDrift(deviceId);
                serialPortHelper.open();//打开串口
                Bundle bundle = serialPortHelper.execute(cmd);
                boolean isSuc = bundle.getBoolean("suc");
                byte[] data = bundle.getByteArray("data");
                onCallback(isSuc, data);
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            } finally {
                serialPortHelper.close();
            }
        }
    }

    /**
     * 写温漂任务
     */
    @SuppressLint("StaticFieldLeak")
    class WriteAsyncTask extends AsyncTask<Void, Void, Boolean> {
        private String loadingText;

        WriteAsyncTask(String loadingText) {
            this.loadingText = loadingText;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            showLoading(loadingText);
        }

        @SuppressLint("WrongThread")
        @Override
        protected Boolean doInBackground(Void... voids) {
            try {
                float[] params = new float[4];
                for (int i = 0; i < mTextViewList.size(); i++) {
                    params[i] = Float.valueOf(mTextViewList.get(i).getText().toString());
                }
                serialPortHelper.open();//打开串口

                Bundle bundle = serialPortHelper.execute(Cmd.setTempDrift(deviceId, params));
                boolean isSuc = bundle.getBoolean("suc");
                if (isSuc) {
                    byte[] data = bundle.getByteArray("data");
                    if (Cmd.cmdValidate(data)) {
                        Logger.e(" 设置温漂成功");
                        return true;
                    } else {
                        Logger.e(TEMP_TYPE_COUNT + " 设置温漂失败");
                        return false;
                    }
                } else {
                    Logger.e(TEMP_TYPE_COUNT + " 设置温漂失败");
                    return false;
                }
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
                return false;
            } finally {
                serialPortHelper.close();
            }
        }

        @Override
        protected void onPostExecute(Boolean result) {
            dismissLoading();
            if (result) {
                ToastUtils.get().showText("保存成功");
            } else {
                ToastUtils.get().showText("保存失败");
            }
        }
    }
}
